home *** CD-ROM | disk | FTP | other *** search
- /*
- ********************************************************************************
- **
- ** Name: DrawSprocketTest.c
- **
- ** Description:
- **
- ** Simple console window application to test the functionality of
- ** DrawSprocket. This application does operations that one would not
- ** normally do when using DrawSprocket in a game, for example providing
- ** bogus input parameters.
- **
- ********************************************************************************
- **
- ** Revision History
- **
- ** 23-Apr-96 CF Converted to final DS naming.
- **
- ********************************************************************************
- */
- #include <Quickdraw.h>
- #include <Events.h>
- #include <Fonts.h>
- #include <Memory.h>
- #include <Windows.h>
- #include <Menus.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <Displays.h>
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <math.h>
- #include <sioux.h>
-
- #include "DrawSprocket.h"
-
- /*
- ********************************************************************************
- ** constants
- ********************************************************************************
- */
- #define kRectSize 16
-
- /*
- ********************************************************************************
- ** globals
- ********************************************************************************
- */
- UInt32 gVBLSync = 1;
- char gTextBuffer[512];
-
- /*
- ********************************************************************************
- ** prototypes
- ********************************************************************************
- */
- void main( void );
- void ErrorMessage( char *inMessage, OSStatus inError );
- void DumpContextAttributes( DSpContextAttributes *inAttributes );
- void MyInitAttributes( DSpContextAttributes *inAttributes );
-
- void TestDrawSprocket( void );
- void TestContextIteration( void );
- void TestContextSearchingAuto( void );
- void TestContextSearchingManual( void );
- void TestContextBuffering( Boolean inUseUnderlay, Boolean inUseOverlay,
- Boolean inUseScaling, Boolean inUseSingleBuffer );
- void TestContextCLUT( void );
- void TestUserSelectContext( void );
-
- /*
- ********************************************************************************
- ** support routines
- ********************************************************************************
- */
- #pragma mark ##### support routines #####
-
- /*
- ********************************************************************************
- **
- ** Name: main
- **
- ** Description:
- **
- ** Program entry point. Starts up and shuts down DrawSprocket.
- **
- ********************************************************************************
- */
- void
- main( void )
- {
- OSStatus theError;
-
- /* tell SIOUX to shut up */
- SIOUXSettings.autocloseonquit = true;
- SIOUXSettings.asktosaveonclose = false;
-
- /* startup DrawSprocket */
- theError = DSpStartup();
- if( theError )
- {
- ErrorMessage( "DSpStartup()", theError );
- return;
- }
-
- /* main test menu */
- TestDrawSprocket();
-
- /* shutdown draw sprocket */
- theError = DSpShutdown();
- if( theError )
- ErrorMessage( "DSpShutdown()", theError );
-
- }
-
- /*
- ********************************************************************************
- **
- ** Name: ErrorMessage
- **
- ** Description:
- **
- ** Prints an error message in human-readable form.
- **
- ********************************************************************************
- */
- void
- ErrorMessage(
- char *inMessage, /* message to display with error code */
- OSStatus inError /* error code */
- )
- {
- UInt32 theIndex;
- static char *theErrorTexts[] = {
- "Unknown Error",
- "kDSpNotInitializedErr",
- "kDSpSystemSWTooOldErr",
- "kDSpInvalidContextErr",
- "kDSpInvalidAttributesErr",
- "kDSpContextAlreadyReservedErr",
- "kDSpContextNotReservedErr",
- "kDSpContextNotFoundErr",
- "kDSpFrameRateNotReadyErr",
- "kDSpConfirmSwitchWarning",
- "kDSpInternalErr"
- };
-
- /* convert the error code into an array index */
- if( inError <= kDSpNotInitializedErr &&
- inError >= kDSpInternalErr )
- {
- theIndex = kDSpNotInitializedErr - inError + 1;
- }
- else
- theIndex = 0;
-
- /* print the message */
- printf("# Error %d (%s) encountered: %s\n", inError,
- theErrorTexts[theIndex], inMessage );
-
- return;
- }
-
- /*
- ********************************************************************************
- **
- ** Name: DumpContextAttributes
- **
- ** Description:
- **
- ** Display the contents of a DSpContextAttributes structure.
- **
- ********************************************************************************
- */
- void
- DumpContextAttributes(
- DSpContextAttributes *inAttributes /* attributes to show */
- )
- {
- printf("\t frequency : ");
- if( inAttributes->frequency )
- printf( "%dhz\n", inAttributes->frequency>>16 );
- else
- printf( "(unknown)\n" );
- printf("\t displayWidth : %d\n", inAttributes->displayWidth );
- printf("\t displayHeight : %d\n", inAttributes->displayHeight );
-
- printf("\t colorNeeds : ");
- switch( inAttributes->colorNeeds )
- {
- case kDSpColorNeeds_DontCare:
- printf("kDSpColorNeeds_DontCare\n");
- break;
-
- case kDSpColorNeeds_Request:
- printf("kDSpColorNeeds_Request\n");
- break;
-
- case kDSpColorNeeds_Require:
- printf("kDSpColorNeeds_Require\n");
- break;
-
- default:
- printf(" %d (Unknown)\n", inAttributes->colorNeeds );
- break;
- }
-
- printf("\t colorTable : 0x%X\n", inAttributes->colorTable );
-
- printf("\t contextOptions : \n");
- if( inAttributes->contextOptions & kDSpContextOption_QD3DAccel )
- printf("\t kDSpContextOption_QD3DAccel\n");
- if( inAttributes->contextOptions & kDSpContextOption_PageFlip )
- printf("\t kDSpContextOption_PageFlip\n");
- if( 0 == inAttributes->contextOptions )
- printf("\t (no options set)\n");
-
- printf("\t backBufferDepthMask : 0x%X\n", inAttributes->backBufferDepthMask );
- printf("\t displayDepthMask : 0x%X\n", inAttributes->displayDepthMask );
- printf("\t backBufferBestDepth : %d\n", inAttributes->backBufferBestDepth );
- printf("\t displayBestDepth : %d\n", inAttributes->displayBestDepth );
- printf("\t pageCount : %d\n", inAttributes->pageCount );
-
- printf("\t gameMustConfirmSwitch : ");
- if( inAttributes->gameMustConfirmSwitch )
- printf("TRUE\n");
- else
- printf("FALSE\n");
- }
-
- /*
- ********************************************************************************
- **
- ** Name: MyInitAttributes
- **
- ** Description:
- **
- ** Initialize a context attributes structure so that there is no garbage
- ** data in it. This is important to do because DS will return an error
- ** if some fields are set incorrectly (including the "reserved" fields not
- ** being set to zero), and some things can actually cause a crash (such
- ** as a bogus color table handle).
- **
- ********************************************************************************
- */
- void
- MyInitAttributes(
- DSpContextAttributes *inAttributes /* attr structure to init */
- )
- {
- if( NULL == inAttributes )
- DebugStr("\pStimpy! You Idiot!");
-
- inAttributes->frequency = 0;
- inAttributes->displayWidth = 0;
- inAttributes->displayHeight = 0;
- inAttributes->reserved1 = 0;
- inAttributes->reserved2 = 0;
- inAttributes->colorNeeds = 0;
- inAttributes->colorTable = NULL;
- inAttributes->contextOptions = 0;
- inAttributes->backBufferDepthMask = 0;
- inAttributes->displayDepthMask = 0;
- inAttributes->backBufferBestDepth = 0;
- inAttributes->displayBestDepth = 0;
- inAttributes->pageCount = 0;
- inAttributes->gameMustConfirmSwitch = false;
- inAttributes->reserved3[0] = 0;
- inAttributes->reserved3[1] = 0;
- inAttributes->reserved3[2] = 0;
- inAttributes->reserved3[3] = 0;
- }
-
- /*
- ********************************************************************************
- ** test routines
- ********************************************************************************
- */
- #pragma mark ##### test routines #####
-
- /*
- ********************************************************************************
- **
- ** Name: TestDrawSprocket
- **
- ** Description:
- **
- ** Main test dispatcher for the DrawSprocket test routines.
- **
- ********************************************************************************
- */
- void
- TestDrawSprocket( void )
- {
- Boolean theDoneFlag = false;
-
- while( false == theDoneFlag )
- {
- UInt32 theChoice;
-
- printf("\n\n############################################################\n");
- printf("DrawSprocket test application.\n");
- printf("Please select from the following tests:\n");
-
- printf("\t 1. Exit\n");
- // printf("\t 2. Run all tests automatically\n");
- // printf("\t 3. Dump information needed for DrawSprocket bug reports\n");
- printf("\t 4. Display/context iteration\n");
- printf("\t 5. Context searching (auto selection of w/h/d/d)\n");
- printf("\t 6. Context searching (you specify w/h/d/d)\n");
- printf("\t 7. Multiple-buffering/page flipping (640x480x8)\n");
- printf("\t 8. CLUT operations\n");
- printf("\t 9. DSpUserSelectContext\n");
- printf("\t10. Underlays\n");
- // printf("\t11. Overlays\n");
- // printf("\t12. Overlays & Underlays\n");
- // printf("\t13. Pixel Scaling\n");
- printf("\t14. Single Buffering\n");
- if( gVBLSync )
- printf("\t15. Disable VBL Sync\n");
- else
- printf("\t15. Enable VBL Sync\n");
-
- printf("\n\tSelection: ");
- gets( gTextBuffer );
- theChoice = atoi( gTextBuffer );
- switch( theChoice )
- {
- /* exit */
- case 1:
- theDoneFlag = true;
- break;
-
- /* context iteration */
- case 4:
- TestContextIteration();
- break;
-
- /* auto context searching */
- case 5:
- TestContextSearchingAuto();
- break;
-
- /* manual context searching */
- case 6:
- TestContextSearchingManual();
- break;
-
- /* buffering */
- case 7:
- TestContextBuffering( false, false, false, false );
- break;
-
- /* CLUT */
- case 8:
- TestContextCLUT();
- break;
-
- /* user select context */
- case 9:
- TestUserSelectContext();
- break;
-
- /* underlay */
- case 10:
- TestContextBuffering( true, false, false, false );
- break;
-
- /* overlay */
- case 11:
- TestContextBuffering( false, true, false, false );
- break;
-
- /* overlay & underlay */
- case 12:
- TestContextBuffering( true, true, false, false );
- break;
-
- /* overlay & underlay & scaling */
- case 13:
- TestContextBuffering( true, true, true, false );
- break;
-
- /* single buffer */
- case 14:
- TestContextBuffering( false, false, false, true );
- break;
-
- /* toggle sync */
- case 15:
- gVBLSync ^= 1;
- break;
-
- /* unknown */
- default:
- printf("\nhuh?\n");
- break;
- }
-
- printf("\nThank you, please drive through.\n");
- }
- }
-
- /*
- ********************************************************************************
- **
- ** Name: TestContextIteration
- **
- ** Description:
- **
- ** Test the ability of DrawSprocket to iterate through the available
- ** display devices and contexts.
- **
- ********************************************************************************
- */
- void
- TestContextIteration( void )
- {
- GDHandle theGDevice;
- OSStatus theError;
-
- printf("\n\n");
- printf("############################################################\n");
- printf("### Testing Display/Context Iteration ###\n");
- printf("############################################################\n");
- printf("\n\n");
-
- /*
- ** Walk the list of display devices in the system. DrawSprocket is
- ** centered around the DisplayIDType, which is used by the Display
- ** Manager. The GDevice records are going to be in flux with future
- ** versions of the system software, so it is best to make the change
- ** now and make your software DisplayManager-centric.
- */
- theGDevice = DMGetFirstScreenDevice( false );
- while( theGDevice )
- {
- DisplayIDType theDisplayID;
- DSpContextReference theContext;
- UInt32 theContextIndex = 0;
-
- /* get the display ID */
- theError = DMGetDisplayIDByGDevice( theGDevice, &theDisplayID,
- false );
- if( theError )
- {
- ErrorMessage( "DMGetDisplayIDByGDevice", theError );
- return;
- }
-
- /* walk the list of contexts for this display */
- theError = DSpGetFirstContext( theDisplayID, &theContext );
- while( noErr == theError )
- {
- DSpContextAttributes theAttributes;
-
- /* obtain the context attributes */
- theError = DSpContext_GetAttributes( theContext, &theAttributes );
- if( theError )
- {
- ErrorMessage( "DSpContext_GetAttributes", theError );
- return;
- }
-
- /* display the attributes structure */
- printf("Display %d, Context %d capabilities:\n", theDisplayID,
- theContextIndex++ );
- DumpContextAttributes( &theAttributes );
-
- /*
- ** get the next context. when a kDSpContextNotFoundErr code
- ** is returned we have hit the end of the context list. if
- ** a different error code is returned, something went wrong.
- */
- theError = DSpGetNextContext( theContext, &theContext );
- if( theError && ( kDSpContextNotFoundErr != theError ) )
- {
- ErrorMessage( "DSpGetNextContext", theError );
- return;
- }
- }
-
- /* next device */
- theGDevice = DMGetNextScreenDevice( theGDevice, false );
- }
- }
-
- /*
- ********************************************************************************
- **
- ** Name: TestContextSearchingAuto
- **
- ** Description:
- **
- ** Test the ability of DrawSprocket to find a context that matches
- ** the requested attributes.
- **
- ********************************************************************************
- */
- void TestContextSearchingAuto( void )
- {
- DSpContextAttributes theDesiredAttributes;
- DSpContextReference theContext;
- OSStatus theError;
-
- printf("\n\n");
- printf("############################################################\n");
- printf("### Testing Display/Context Searching ###\n");
- printf("############################################################\n");
- printf("\n\n");
-
- /*
- ** Find a 320x200x8 mode
- **
- ** First, init the attributes so that there will be no garbage in any
- ** of the fields (and which will cause DS to return an error). This
- ** is especially important for fields that DS can't check, such as
- ** the colorTable. If the colorTable is bogus when a call to reserve
- ** a context is made, then it will try to use the bogus color table
- ** (causing unpleasant visits to the debugger).
- **
- ** When using DSpFindBestContext(), the attributes are interpreted as
- ** *REQUIREMENTS*, unlike when you call DSpContext_Reserve(), when
- ** they are interpreted as *REQUESTS*. If I specify a contextOption
- ** of kDSpContextOption_PageFlip here, only contexts with the ability
- ** to page flip will be considered in the search, however if I specify
- ** the same option when reserving the context, and page flipping is not
- ** available, then DS will use software double/triple buffering. This
- ** is so to make it easy for the game to always request that DS use
- ** page flipping if it is there (at reservation time), but still continue
- ** if it is not. Conversely, the game can search for only contexts
- ** that meet a specific criteria, and know that any matches found will
- ** meet those specifications.
- */
- MyInitAttributes( &theDesiredAttributes );
- theDesiredAttributes.displayWidth = 320;
- theDesiredAttributes.displayHeight = 200;
- theDesiredAttributes.colorNeeds = kDSpColorNeeds_Require;
- theDesiredAttributes.backBufferDepthMask = kDSpDepthMask_8;
- theDesiredAttributes.displayDepthMask = kDSpDepthMask_8;
- theDesiredAttributes.backBufferBestDepth = 8;
- theDesiredAttributes.displayBestDepth = 8;
- theDesiredAttributes.pageCount = 2;
- theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
- if( theError && kDSpContextNotFoundErr != theError )
- {
- ErrorMessage( "DSpFindBestContext 320x200x8", theError );
- return;
- }
- if( kDSpContextNotFoundErr == theError )
- {
- printf("# Unable to find a matching context for the following attributes:\n");
- DumpContextAttributes( &theDesiredAttributes );
- return;
- }
- else
- {
- DSpContextAttributes theActualAttributes;
- DisplayIDType theDisplayID;
-
- /* get the actual attributes for the context */
- theError = DSpContext_GetAttributes( theContext, &theActualAttributes );
- if( theError )
- {
- ErrorMessage( "DSpContext_GetAttributes", theError );
- return;
- }
-
- /* get the display id for the context */
- theError = DSpContext_GetDisplayID( theContext, &theDisplayID );
- if( theError )
- {
- ErrorMessage( "DSpContext_GetDisplayID", theError );
- return;
- }
-
- /* tell the user about the results */
- printf("Best matching Context for the following attributes...\n");
- DumpContextAttributes( &theDesiredAttributes );
-
- printf("...is the context on display id %d with these attributes:\n",
- theDisplayID );
- DumpContextAttributes( &theActualAttributes );
- }
- }
-
- /*
- ********************************************************************************
- **
- ** Name: TestContextSearchingManual
- **
- ** Description:
- **
- ** Test the ability of DrawSprocket to find a context that matches
- ** the requested attributes, but let the user choose the attributes.
- **
- ********************************************************************************
- */
- void TestContextSearchingManual( void )
- {
- DSpContextAttributes theDesiredAttributes;
- DSpContextReference theContext;
- OSStatus theError;
-
- printf("\n\n");
- printf("############################################################\n");
- printf("### Testing Display/Context Searching ###\n");
- printf("############################################################\n");
- printf("\n\n");
-
- /* get the context attributes */
- MyInitAttributes( &theDesiredAttributes );
- theDesiredAttributes.pageCount = 2;
-
- printf("enter the display width: ");
- gets(gTextBuffer);
- theDesiredAttributes.displayWidth = atoi(gTextBuffer);
- if( 0 == theDesiredAttributes.displayWidth )
- {
- printf("bogus value!\n");
- return;
- }
-
- printf("enter the display height: ");
- gets(gTextBuffer);
- theDesiredAttributes.displayHeight = atoi(gTextBuffer);
- if( 0 == theDesiredAttributes.displayHeight )
- {
- printf("bogus value!\n");
- return;
- }
-
- printf("enter the back buffer best depth: ");
- gets(gTextBuffer);
- theDesiredAttributes.backBufferBestDepth = atoi(gTextBuffer);
- if( 0 == theDesiredAttributes.backBufferBestDepth )
- {
- printf("bogus value!\n");
- return;
- }
-
- printf("enter the display best depth: ");
- gets(gTextBuffer);
- theDesiredAttributes.displayBestDepth = atoi(gTextBuffer);
- if( 0 == theDesiredAttributes.displayBestDepth )
- {
- printf("bogus value!\n");
- return;
- }
-
- theDesiredAttributes.colorNeeds = kDSpColorNeeds_Require;
- theDesiredAttributes.backBufferDepthMask = theDesiredAttributes.backBufferBestDepth;
- theDesiredAttributes.displayDepthMask = theDesiredAttributes.displayBestDepth;
-
- /* find the context */
- theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
- if( theError && kDSpContextNotFoundErr != theError )
- {
- ErrorMessage( "DSpFindBestContext (Manual)", theError );
- return;
- }
- if( kDSpContextNotFoundErr == theError )
- {
- printf("# Unable to find a matching context for the following attributes:\n");
- DumpContextAttributes( &theDesiredAttributes );
- return;
- }
- else
- {
- DSpContextAttributes theActualAttributes;
- DisplayIDType theDisplayID;
-
- /* get the actual attributes for the context */
- theError = DSpContext_GetAttributes( theContext, &theActualAttributes );
- if( theError )
- {
- ErrorMessage( "DSpContext_GetAttributes", theError );
- return;
- }
-
- /* get the display id for the context */
- theError = DSpContext_GetDisplayID( theContext, &theDisplayID );
- if( theError )
- {
- ErrorMessage( "DSpContext_GetDisplayID", theError );
- return;
- }
-
- /* tell the user about the results */
- printf("Best matching Context for the following attributes...\n");
- DumpContextAttributes( &theDesiredAttributes );
-
- printf("...is the context on display id %d with these attributes:\n",
- theDisplayID );
- DumpContextAttributes( &theActualAttributes );
- }
- }
-
- /*
- ********************************************************************************
- **
- ** Name: TestContextBuffering
- **
- ** Description:
- **
- ** Test the ability of DrawSprocket to sw buffer or page flip an image.
- **
- ********************************************************************************
- */
- void TestContextBuffering(
- Boolean inUseUnderlay,
- Boolean inUseOverlay,
- Boolean inUseScaling,
- Boolean inUseSingleBuffer
- )
- {
- DSpContextAttributes theDesiredAttributes;
- DSpContextReference theContext;
- OSStatus theError;
- DSpAltBufferReference theUnderlay, theOverlay;
- UInt32 theDisplayWidth, theDisplayHeight;
-
- printf("\n\n");
- printf("############################################################\n");
- printf("### Testing Buffering ###\n");
- printf("############################################################\n");
- printf("\n\n");
-
-
- /* find the context */
- MyInitAttributes( &theDesiredAttributes );
- theDesiredAttributes.displayWidth = 640;
- theDesiredAttributes.displayHeight = 480;
- theDesiredAttributes.colorNeeds = kDSpColorNeeds_Require;
- theDesiredAttributes.backBufferDepthMask = kDSpDepthMask_8;
- theDesiredAttributes.displayDepthMask = kDSpDepthMask_8;
- theDesiredAttributes.backBufferBestDepth = 8;
- theDesiredAttributes.displayBestDepth = 8;
- theDesiredAttributes.pageCount = 2;
- if( inUseSingleBuffer )
- theDesiredAttributes.pageCount = 1;
- theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
- if( theError && kDSpContextNotFoundErr != theError )
- {
- ErrorMessage( "DSpFindBestContext", theError );
- return;
- }
- if( kDSpContextNotFoundErr == theError )
- {
- printf("# Unable to find a matching context for the following attributes:\n");
- DumpContextAttributes( &theDesiredAttributes );
- return;
- }
-
- theDisplayWidth = 640;
- theDisplayHeight = 480;
-
- /*
- ** Here is where I need to OR in the value to use page flipping. If
- ** I had used the value when calling DSpFindBestContext() then it would
- ** have only considered displays that have page flipping hardware, but
- ** I want to run with software buffering too.
- */
- theDesiredAttributes.contextOptions |= kDSpContextOption_PageFlip;
-
- /*
- ** If page flipping isn't available, then software buffering will
- ** be used. DS can use double or triple buffering depending on the
- ** state of the kDSpContextOption_TripleBuffer option bit.
- **
- ** If you only want double buffering, perhaps because of memory
- ** constraints (a certain person named BG comes to mind, don't
- ** go postal on me BG :-), then you should turn off the option bit.
- **
- ** If you leave the bit on and there is hardware page flipping
- ** available (and you haven't turned off that option bit), but
- ** there are only 2 video pages (not three) then DS will consider
- ** page flipping to be more important of an option than triple
- ** buffering and will drop you down to 2 VRAM pages (leaving you
- ** still page flipping).
- **
- */
- /*
- theDesiredAttributes.contextOptions &= ~kDSpContextOption_TripleBuffer;
- */
-
- /*
- ** set vbl sync
- */
- if( false == gVBLSync )
- theDesiredAttributes.contextOptions |= kDSpContextOption_DontSyncVBL;
-
- /* reserve the context */
- theError = DSpContext_Reserve( theContext, &theDesiredAttributes );
- if( theError )
- {
- ErrorMessage( "DSpContext_Reserve", theError );
- return;
- }
-
- #if 0
- if( inUseScaling )
- {
- theError = DSpContext_SetScale( theContext, kDSpBufferScale_2 );
- if( theError )
- {
- ErrorMessage( "DSpContext_SetScale", theError );
- return;
- }
-
- theDisplayWidth = 320;
- theDisplayHeight = 240;
- }
- #endif
-
- /*
- ** allocate an alt buffer that will be used for the underlay. An
- ** underlay is useful in games that have a need to restore from a
- ** static background.
- */
- theError = DSpAltBuffer_New( theContext, false, 0, &theUnderlay );
- if( theError )
- {
- DSpContext_Release( theContext );
- ErrorMessage( "DSpAltBuffer_New (underlay)", theError );
- return;
- }
-
- theError = DSpContext_SetUnderlayAltBuffer( theContext, theUnderlay );
- if( theError )
- {
- DSpContext_Release( theContext );
- ErrorMessage( "DSpContext_SetUnderlayAltBuffer", theError );
- return;
- }
-
- #if 0
- /*
- ** allocate an alt buffer that will be used as an overlay. An overlay
- ** is useful for things such as a cockpit view that is superimposed
- ** on the back buffer before it is displayed.
- */
- if( inUseOverlay )
- {
- CGrafPtr theAltBufferPort;
- GDHandle theAltBufferGDevice, theOldGDevice;
- GrafPtr theOldPort;
-
- GetPort( &theOldPort );
- theOldGDevice = GetGDevice();
-
- theError = DSpAltBuffer_New( theContext, false, 0, &theOverlay );
- if( theError )
- {
- DSpContext_Release( theContext );
- ErrorMessage( "DSpAltBuffer_New (overlay)", theError );
- return;
- }
-
- theError = DSpContext_SetOverlayAltBuffer( theContext, theOverlay );
- if( theError )
- {
- DSpContext_Release( theContext );
- ErrorMessage( "DSpContext_SetOverlayAltBuffer", theError );
- return;
- }
-
- /*
- ** fill the overlay buffer with a pattern
- */
- theError = DSpAltBuffer_GetCGrafPtr( theOverlay,
- kDSpBufferKind_Normal, &theAltBufferPort, &theAltBufferGDevice );
- if( theError )
- {
- ErrorMessage( "DSpAltBuffer_GetCGrafPtr (overlay)", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /*
- ** if you want to use QuickDraw or any other toolbox rendering
- ** code, you must setup the GDevice as well as the port when
- ** working with AltBuffers!
- */
- SetPort( (GrafPtr)theAltBufferPort );
- SetGDevice( theAltBufferGDevice );
-
- ForeColor( redColor );
- TextSize(96);
- MoveTo( 100, 200 );
- DrawText( "Overlay!", 0, 8 );
-
- SetPort( theOldPort );
- SetGDevice( theOldGDevice );
- }
- #endif
-
- /*
- ** If you are in a debug cycle, you may want to enable debugging mode
- ** in DrawSprocket so that a fade out, followed by a break in the
- ** debugger, won't leave you with nothing to see.
- **
- ** You can also create a folder in same folder as your game, and name
- ** it "DSpSetDebugMode", this will also cause DSp to enter debug mode.
- ** This method is handy if you don't want to rebuild your game with
- ** the call just to debug it.
- */
- //DSpSetDebugMode( true );
-
- /*
- ** fade out all displays to black, you must have at least one reserved
- ** context to do this or you will get an error. A game should always
- ** fade to black before activating a context because if the activation
- ** causes a resolution change the user will see a very ugly twitch in
- ** the display.
- */
- theError = DSpContext_FadeGammaOut( NULL, NULL );
- if( theError )
- {
- ErrorMessage( "DSpContext_FadeGammaOut", theError );
- DSpContext_FadeGammaIn( NULL, NULL );
- DSpContext_Release( theContext );
- return;
- }
-
- /* put the context into the active state */
- theError = DSpContext_SetState( theContext, kDSpContextState_Active );
- if( theError )
- {
- ErrorMessage( "DSpContext_SetState", theError );
- DSpContext_FadeGammaIn( NULL, NULL );
- DSpContext_Release( theContext );
- return;
- }
-
- /* fade back in */
- theError = DSpContext_FadeGammaIn( NULL, NULL );
- if( theError )
- {
- ErrorMessage( "DSpContext_FadeGammaIn", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /*
- ****************************************************************************
- ** do the double buffering
- ****************************************************************************
- */
- {
- UInt32 thePosition, theColorIndex, theXPos, theYPos;
- CGrafPtr theAltBufferPort;
- GDHandle theAltBufferGDevice, theOldGDevice;
- Rect theRect;
- GrafPtr theOldPort;
-
- GetPort( &theOldPort );
- theOldGDevice = GetGDevice();
-
- /* set the alt buffer to be the current port */
- theError = DSpAltBuffer_GetCGrafPtr( theUnderlay,
- kDSpBufferKind_Normal, &theAltBufferPort, &theAltBufferGDevice );
- if( theError )
- {
- ErrorMessage( "DSpAltBuffer_GetCGrafPtr (underlay)", theError );
- DSpContext_FadeGammaIn( NULL, NULL );
- DSpContext_Release( theContext );
- return;
- }
-
- /*
- ** if you want to use QuickDraw or any other toolbox rendering
- ** code, you must setup the GDevice as well as the port when
- ** working with AltBuffers!
- */
- SetPort( (GrafPtr)theAltBufferPort );
- SetGDevice( theAltBufferGDevice );
-
- /*
- ** fill the underlay buffer with a pattern or clear it
- */
- if( inUseUnderlay )
- {
- /*
- ** draw a pattern into the underlay buffer. this pattern will be
- ** restored every time I get the back buffer
- */
- theColorIndex = 0;
- for( theYPos = 0; theYPos < theDesiredAttributes.displayHeight;
- theYPos += kRectSize )
- {
- for( theXPos = 0; theXPos < theDesiredAttributes.displayWidth;
- theXPos += kRectSize )
- {
- SetRect( &theRect, 0, 0, kRectSize, kRectSize );
- OffsetRect( &theRect, theXPos, theYPos );
- theAltBufferPort->fgColor = theColorIndex % 255;
-
- PaintRect( &theRect );
-
- theColorIndex++;
- }
- }
- }
- else
- {
- ForeColor( blackColor );
- BackColor( whiteColor );
- SetRect( &theRect, 0, 0, theDesiredAttributes.displayWidth,
- theDesiredAttributes.displayHeight );
- EraseRect( &theRect );
- }
-
- SetPort( theOldPort );
- SetGDevice( theOldGDevice );
- }
-
- /*
- ** this test slides a black vertical bar left and right on the
- ** display, producing an image where any tearing is amplified.
- */
- {
-
- RGBColor theColor, theTextColor;
- Rect theRectangleRect, theRect;
- UInt32 theStartTick, theMaxTick, theCurrentTick;
- UInt32 theCount, theRectangleDelta;
- UInt32 theWidth, theXPos, theYPos;
- CGrafPtr theBackBuffer;
-
- theColor.red = 0;
- theColor.green = 0;
- theColor.blue = 0;
- theTextColor.red = 0xFFFF;
- theTextColor.green = 0xFFFF;
- theTextColor.blue = 0xFFFF;
-
- /* rectangle will be 1/8 the display width, and all of the height */
- SetRect( &theRectangleRect, 0, 0, theDesiredAttributes.displayWidth >> 3,
- theDesiredAttributes.displayHeight );
-
- theStartTick = theCurrentTick = TickCount();
- theMaxTick = theStartTick + (15 * 60);
- theCount = 0;
- theRectangleDelta = 3;
- while( theCurrentTick < theMaxTick )
- {
-
- /* get the back buffer */
- theError = DSpContext_GetBackBuffer( theContext, kDSpBufferKind_Normal,
- &theBackBuffer );
- if( theError )
- {
- ErrorMessage( "DSpContext_GetBackBuffer", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /* set the back buffer to be the current port */
- SetPort( (GrafPtr)theBackBuffer );
-
- /* fill the display with a sliding vertical rectangle */
- RGBForeColor( &theColor );
- PaintRect( &theRectangleRect );
-
- /* inval the new rect position */
- theError = DSpContext_InvalBackBufferRect( theContext,
- &theRectangleRect );
-
- if( (theRectangleRect.right + theRectangleDelta) > theDesiredAttributes.displayWidth )
- theRectangleDelta = -theRectangleDelta;
-
- if ( (theRectangleRect.left + theRectangleDelta) < 0 )
- theRectangleDelta = -theRectangleDelta;
-
- theRectangleRect.left += theRectangleDelta;
- theRectangleRect.right += theRectangleDelta;
-
- // draw a frame counter
- sprintf((char *)&gTextBuffer[1],
- "This is frame %d (%d ticks remaining, %.1f fps)",
- theCount + 1, theMaxTick - theCurrentTick,
- (float)(theCount / ((theCurrentTick - theStartTick) / 60.0)) );
- gTextBuffer[0] = strlen( (char *)&gTextBuffer[1] );
- theWidth = StringWidth( (ConstStr255Param)gTextBuffer );
- theXPos = ( theDisplayWidth >> 1 ) - ( theWidth >> 1 );
- theYPos = theDisplayHeight - 20;
-
- theTextColor.red = 0;
- theTextColor.green = 0;
- theTextColor.blue = 0;
- RGBForeColor( &theTextColor );
- SetRect( &theRect, theXPos - 10, theYPos - 20, theXPos + theWidth + 10, theYPos + 10 );
- PaintRect( &theRect );
-
- theError = DSpContext_InvalBackBufferRect( theContext,
- &theRect );
-
- theTextColor.red = 0;
- theTextColor.green = 0xFFFF;
- theTextColor.blue = 0xFFFF;
- RGBForeColor( &theTextColor );
- FrameRect( &theRect );
-
- MoveTo( theXPos, theYPos );
- DrawString( (ConstStr255Param)gTextBuffer );
-
- // swap the buffers
- theError = DSpContext_SwapBuffers( theContext, NULL, 0 );
- if( theError )
- {
- ErrorMessage( "DSpContext_SwapBuffers", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /* increase frame counter */
- theCount++;
- theCurrentTick = TickCount();
- }
-
- }
-
- /*
- ****************************************************************************
- ** cleanup
- ****************************************************************************
- */
-
- /* fade to black */
- theError = DSpContext_FadeGammaOut( NULL, NULL );
- if( theError )
- {
- ErrorMessage( "DSpContext_FadeGammaIn", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /* remove the underlay & release it */
- DSpContext_SetUnderlayAltBuffer( theContext, NULL );
- DSpAltBuffer_Dispose( theUnderlay );
- theUnderlay = NULL;
-
- #if 0
- /* remove the overlay & release it */
- if( inUseOverlay )
- {
- DSpContext_SetOverlayAltBuffer( theContext, NULL );
- DSpAltBuffer_Dispose( theOverlay );
- theOverlay = NULL;
- }
- #endif
-
- /* put the context into the inactive state */
- theError = DSpContext_SetState( theContext, kDSpContextState_Inactive );
- if( theError )
- {
- ErrorMessage( "DSpContext_SetState", theError );
- DSpContext_FadeGammaIn( NULL, NULL );
- DSpContext_Release( theContext );
- return;
- }
-
- /* fade back in */
- theError = DSpContext_FadeGammaIn( NULL, NULL );
- if( theError )
- {
- ErrorMessage( "DSpContext_FadeGammaIn", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /* release the context */
- theError = DSpContext_Release( theContext );
- if( theError )
- {
- ErrorMessage( "DSpContext_Release", theError );
- return;
- }
- }
-
- /*
- ********************************************************************************
- **
- ** Name: TestContextCLUT
- **
- ** Description:
- **
- ** Test the ability of DrawSprocket to manipulate the CLUT.
- **
- ********************************************************************************
- */
- void TestContextCLUT( void )
- {
- DSpContextAttributes theDesiredAttributes;
- DSpContextReference theContext;
- OSStatus theError;
- RGBColor theBlankingColor;
-
- printf("\n\n");
- printf("############################################################\n");
- printf("### Testing CLUT ###\n");
- printf("############################################################\n");
- printf("\n\n");
-
-
- /* find the context */
- MyInitAttributes( &theDesiredAttributes );
- theDesiredAttributes.displayWidth = 640;
- theDesiredAttributes.displayHeight = 480;
- theDesiredAttributes.colorNeeds = kDSpColorNeeds_Require;
- theDesiredAttributes.backBufferDepthMask = kDSpDepthMask_8;
- theDesiredAttributes.displayDepthMask = kDSpDepthMask_8;
- theDesiredAttributes.backBufferBestDepth = 8;
- theDesiredAttributes.displayBestDepth = 8;
- theDesiredAttributes.pageCount = 2;
- theError = DSpFindBestContext( &theDesiredAttributes, &theContext );
- if( theError && kDSpContextNotFoundErr != theError )
- {
- ErrorMessage( "DSpFindBestContext", theError );
- return;
- }
- if( kDSpContextNotFoundErr == theError )
- {
- printf("# Unable to find a matching context for the following attributes:\n");
- DumpContextAttributes( &theDesiredAttributes );
- return;
- }
-
- /* reserve the context */
- theError = DSpContext_Reserve( theContext, &theDesiredAttributes );
- if( theError )
- {
- ErrorMessage( "DSpContext_Reserve", theError );
- return;
- }
-
- /* set the blanking color to white, just for the heck of it */
- theBlankingColor.red = 0xFFFFF;
- theBlankingColor.green = 0xFFFFF;
- theBlankingColor.blue = 0xFFFFF;
- theError = DSpSetBlankingColor( &theBlankingColor );
- if( theError )
- {
- ErrorMessage( "DSpSetBlankingColor", theError );
- return;
- }
-
- /* fade out all displays to black */
- theError = DSpContext_FadeGammaOut( NULL, NULL );
- if( theError )
- {
- ErrorMessage( "DSpContext_FadeGammaOut", theError );
- DSpContext_FadeGammaIn( NULL, NULL );
- DSpContext_Release( theContext );
- return;
- }
-
- /* put the context into the active state */
- theError = DSpContext_SetState( theContext, kDSpContextState_Active );
- if( theError )
- {
- ErrorMessage( "DSpContext_SetState", theError );
- DSpContext_FadeGammaIn( NULL, NULL );
- DSpContext_Release( theContext );
- return;
- }
-
- /* fade back in */
- theError = DSpContext_FadeGammaIn( NULL, NULL );
- if( theError )
- {
- ErrorMessage( "DSpContext_FadeGammaIn", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /*
- ****************************************************************************
- ** do the CLUT testing
- ****************************************************************************
- */
-
- /* draw a pattern into the back buffer and cycle it */
- {
- UInt32 thePosition, theColorIndex, theXPos, theYPos;
- CGrafPtr theBackBuffer;
- ColorSpec theOriginalColors[256];
- Rect theRect;
-
- /* get the back buffer */
- theError = DSpContext_GetBackBuffer( theContext, kDSpBufferKind_Normal,
- &theBackBuffer );
- if( theError )
- {
- ErrorMessage( "DSpContext_GetBackBuffer", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /* set the back buffer to be the current port */
- SetPort( (GrafPtr)theBackBuffer );
-
- /* draw a pattern into the back buffer */
- theColorIndex = 0;
- for( theYPos = 0; theYPos < theDesiredAttributes.displayHeight;
- theYPos += kRectSize )
- {
- for( theXPos = 0; theXPos < theDesiredAttributes.displayWidth;
- theXPos += kRectSize )
- {
- Rect theRect;
-
- SetRect( &theRect, 0, 0, kRectSize, kRectSize );
- OffsetRect( &theRect, theXPos, theYPos );
- theBackBuffer->fgColor = theColorIndex % 255;
-
- PaintRect( &theRect );
-
- theColorIndex++;
- }
- }
-
- /* bring the back buffer to the front */
- theError = DSpContext_SwapBuffers( theContext, NULL, 0 );
- if( theError )
- {
- ErrorMessage( "DSpContext_SwapBuffers", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /*
- ** get the original color table
- **
- ** unfortunately, these probably aren't the real colors, since
- ** the way that gamma works on the Mac is to remap the indexed
- ** color table to new colors. In other words, these colors are
- ** gamma corrected versions of the ones that were originally set.
- **
- */
- theError = DSpContext_GetCLUTEntries( theContext, theOriginalColors,
- 0, 255 );
- if( theError )
- {
- ErrorMessage( "DSpContext_GetCLUTEntries", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /* cycle the colors */
- while( !Button() )
- {
- ColorSpec theSpec[256], theTempSpec;
-
- /* rotate them */
- theTempSpec = theOriginalColors[0];
-
- for( theColorIndex = 0; theColorIndex < 255; theColorIndex++ )
- theSpec[theColorIndex].rgb =
- theOriginalColors[(theColorIndex + thePosition) % 255].rgb;
-
- theSpec[255].rgb = theTempSpec.rgb;
-
- thePosition++;
- if( thePosition > 255 )
- thePosition = 0;
-
- /* set the entries */
- theError = DSpContext_SetCLUTEntries( theContext, theSpec, 0, 255 );
- if( theError )
- {
- ErrorMessage( "DSpContext_SetCLUTEntries", theError );
- DSpContext_Release( theContext );
- return;
- }
- }
-
- }
-
- /*
- ****************************************************************************
- ** cleanup
- ****************************************************************************
- */
-
- /* fade to black */
- theError = DSpContext_FadeGammaOut( NULL, NULL );
- if( theError )
- {
- ErrorMessage( "DSpContext_FadeGammaIn", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /* put the context into the inactive state */
- theError = DSpContext_SetState( theContext, kDSpContextState_Inactive );
- if( theError )
- {
- ErrorMessage( "DSpContext_SetState", theError );
- DSpContext_FadeGammaIn( NULL, NULL );
- DSpContext_Release( theContext );
- return;
- }
-
- /* fade back in */
- theError = DSpContext_FadeGammaIn( NULL, NULL );
- if( theError )
- {
- ErrorMessage( "DSpContext_FadeGammaIn", theError );
- DSpContext_Release( theContext );
- return;
- }
-
- /* release the context */
- theError = DSpContext_Release( theContext );
- if( theError )
- {
- ErrorMessage( "DSpContext_Release", theError );
- return;
- }
- }
-
- void
- TestUserSelectContext( void )
- {
- DSpContextAttributes theDesiredAttributes;
- DSpContextAttributes theActualAttributes;
- DSpContextReference theContext;
- OSStatus theError;
- RGBColor theBlankingColor;
- Boolean theShowDialogFlag;
- DisplayIDType theDisplayID;
-
- printf("\n\n");
- printf("############################################################\n");
- printf("### Testing CLUT ###\n");
- printf("############################################################\n");
- printf("\n\n");
-
-
- /* find the context */
- MyInitAttributes( &theDesiredAttributes );
- theDesiredAttributes.displayWidth = 640;
- theDesiredAttributes.displayHeight = 480;
- theDesiredAttributes.colorNeeds = kDSpColorNeeds_Require;
- theDesiredAttributes.backBufferDepthMask = kDSpDepthMask_8;
- theDesiredAttributes.displayDepthMask = kDSpDepthMask_8;
- theDesiredAttributes.backBufferBestDepth = 8;
- theDesiredAttributes.displayBestDepth = 8;
- theDesiredAttributes.pageCount = 2;
-
- /*
- ** see if there are enough choices available for the user to
- ** choose from, this can be used if I needed to determine
- ** whether or not to enable a menu item, etc.
- */
- theError = DSpCanUserSelectContext( &theDesiredAttributes,
- &theShowDialogFlag );
- if( theError )
- {
- ErrorMessage( "DSpCanUserSelectContext", theError );
- return;
- }
- if( false == theShowDialogFlag )
- {
- printf("There are not enough choices to warrant asking the user.\n");
- return;
- }
-
- /*
- ** put up the choice dialog, I don't care about what display it
- ** appears on, nor do I care to know about update events
- */
- theError = DSpUserSelectContext( &theDesiredAttributes, 0,
- NULL, &theContext );
- if( theError )
- {
- /*
- ** since we know that there were possible matches available (because
- ** we called DSpCanUserSelectContext), we know that a context-not-found
- ** error means that the user canceled the dialog
- */
- if( kDSpContextNotFoundErr == theError )
- printf("The user canceled the dialog.\n");
- else
- ErrorMessage( "DSpUserSelectContext", theError );
- return;
- }
-
- /* tell the user about the results */
- printf("User-Selected Context for the following attributes...\n");
- DumpContextAttributes( &theDesiredAttributes );
-
- theError = DSpContext_GetDisplayID( theContext, &theDisplayID );
- if( theError )
- {
- ErrorMessage( "DSpContext_GetDisplayID", theError );
- return;
- }
-
- theError = DSpContext_GetAttributes( theContext, &theActualAttributes );
- if( theError )
- {
- ErrorMessage( "DSpContext_GetAttributes", theError );
- return;
- }
-
- printf("...is the context on display id %d with these attributes:\n",
- theDisplayID );
- DumpContextAttributes( &theActualAttributes );
- }
-